import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fsharing/core/constants/app_contstants.dart';
import 'package:fsharing/core/models/account.dart';
import 'package:fsharing/core/models/account_detail.dart';
import 'package:fsharing/core/models/ad.dart';
import 'package:fsharing/core/models/address.dart' as address;
import 'package:fsharing/core/models/bank.dart';
import 'package:fsharing/core/models/business_apply.dart';
import 'package:fsharing/core/models/business_condition.dart';
import 'package:fsharing/core/models/business_level.dart';
import 'package:fsharing/core/models/business_type.dart';
import 'package:fsharing/core/models/cart_add.dart';
import 'package:fsharing/core/models/cart_list.dart';
import 'package:fsharing/core/models/logistics.dart';
import 'package:fsharing/core/models/message.dart';
import 'package:fsharing/core/models/news_query.dart';
import 'package:fsharing/core/models/order_confirm.dart';
import 'package:fsharing/core/models/order_detail.dart';
import 'package:fsharing/core/models/order_list.dart';
import 'package:fsharing/core/models/product_detail.dart';
import 'package:fsharing/core/models/search.dart';
import 'package:fsharing/core/models/store_apply_query.dart';
import 'package:fsharing/core/models/store_categories.dart';
import 'package:fsharing/core/models/store_detail.dart';
import 'package:fsharing/core/models/store_index.dart';
import 'package:fsharing/core/models/store_product_query.dart';
import 'package:fsharing/core/models/store_search.dart';
import 'package:fsharing/core/models/store_total.dart';
import 'package:fsharing/core/models/user_invited.dart';
import 'package:fsharing/core/models/user_renew_list.dart';
import 'package:fsharing/core/models/user_total.dart';
import 'package:fsharing/core/models/withdraw.dart';
import 'package:fsharing/core/services/auth.dart';
import 'package:fsharing/core/services/dio_interceptor.dart';
import 'package:fsharing/core/viewmodels/app_model.dart';

class Api {
  static const _clientId = Auth.clientId;

  final Dio _mainClient;

  Api(AppStoreModel appStoreModel, AppLoginModel appLoginModel)
      : _mainClient = Dio()
          ..options.baseUrl = api_base_url
          ..options.connectTimeout = 5000
          ..options.sendTimeout = 5000
          ..options.receiveTimeout = 5000
          ..interceptors.add(DioInterceptor(appStoreModel, appLoginModel))
          ..interceptors.add(LogInterceptor(requestBody: true, responseBody: true)) {
    debugPrint('$this init');
  }

  /// 启动页广告
  Future<List<Ad>> adStart(CancelToken cancelToken) async {
    var params = {'clientId': _clientId, 'linkType': 'START_AD', 'storeId': '0'};
    var response = await _mainClient.post('/api/ad/start', data: params, cancelToken: cancelToken);
    return response.data.map<Ad>((value) => Ad.fromJson(value)).toList();
  }

  /// 首页数据
  Future<StoreIndex> storeIndex(int bindingStoreId, int storeInt, CancelToken cancelToken) async {
    var params = {'bsid': bindingStoreId, 'sid': storeInt};
    var response = await _mainClient.get('/api/store/index',
        queryParameters: params, cancelToken: cancelToken);
    return StoreIndex.fromJson(response.data);
  }

  /// 商品详情
  Future<ProductDetail> productDetail(
    int areaId,
    int mid,
    int referStoreId,
    CancelToken cancelToken,
  ) async {
    var params = {'aid': areaId, 'mid': mid, 'r': referStoreId};
    var response = await _mainClient.get(
      '/api/product/detail',
      queryParameters: params,
      cancelToken: cancelToken,
    );
    return ProductDetail.fromJson(response.data);
  }

  /// 加入购物车
  Future<CartAdd> cartAdd(int mid, int quantity, String referStoreId) async {
    var params = {'mia': mid, 'quantity': quantity, 'r': referStoreId};
    var response = await _mainClient.post('/api/cart/add', data: FormData.fromMap(params));
    return CartAdd.fromJson(response.data);
  }

  /// 检查能否下单
  Future orderCheck(Map<String, int> cartIdQuantity) async {
    var response = await _mainClient.post('/api/order/check', data: cartIdQuantity);
    return response.data;
  }

  /// 获取订单确认数据
  Future<OrderConfirm> orderConfirm(Map<String, int> cartIdQuantity) async {
    var response = await _mainClient.post('/api/order/confirm', data: cartIdQuantity);
    return OrderConfirm.fromJson(response.data);
  }

  /// 地址列表
  Future<List<address.Address>> addressList() async {
    var response = await _mainClient.get('/api/address/list');
    return response.data.map<address.Address>((value) => address.Address.fromJson(value)).toList();
  }

  /// 行政区查询
  Future<Map<String, dynamic>> addressRegionQuery(String id) async {
    var params = {'p': id};
    var response = await _mainClient.get('/api/address/region/query', queryParameters: params);
    return response.data;
  }

  /// 创建或更新用户配送地址
  Future addressUpdate(address.Address address) async {
    var response = await _mainClient.post('/api/address/update', data: address);
    return response.data;
  }

  /// 地址删除
  Future addressDelete(int addressId) async {
    var response = await _mainClient.get('/api/address/delete/$addressId');
    return response.data;
  }

  /// 地址验证码发送
  Future<String> addressSms(String phone) async {
    var response = await _mainClient.get('/api/address/sms/$phone');
    return response.data;
  }

  /// 购物车列表
  Future<CartList> cartList(CancelToken cancelToken) async {
    var response = await _mainClient.get('/api/cart/list', cancelToken: cancelToken);
    return CartList.fromJson(response.data);
  }

  /// 购物车数量变更
  Future cartChange(int cartId, int quantity) async {
    var params = {'shopCartId': cartId, 'quantity': quantity};
    var response = await _mainClient.post('/api/cart/change', data: FormData.fromMap(params));
    return response.data;
  }

  /// 购物车记录删除
  Future cartRemove(int cartId) async {
    var params = {'shopCartId': cartId};
    var response = await _mainClient.post('/api/cart/remove', data: FormData.fromMap(params));
    return response.data;
  }

  /// 提交订单，并支付
  Future orderCheckout(
    int addressId,
    String payType,
    Map<String, int> storeCarts,
    Map<String, String> other,
  ) async {
    var params = {
      'addressId': addressId,
      'openid': '未知',
      'payType': payType,
      'source': 'APP',
      'storeCarts': jsonEncode(storeCarts)
    };
    var response = await _mainClient.post(
      '/api/order/checkout',
      data: FormData.fromMap(other),
      queryParameters: params,
    );
    return response.data;
  }

  /// 用户各类信息统计数量
  Future<UserTotal> userTotal(CancelToken cancelToken) async {
    var response = await _mainClient.get('/api/user/total', cancelToken: cancelToken);
    return UserTotal.fromJson(response.data);
  }

  /// 订单列表
  /// status 订单状态：1待支付，2待发货，3待收货，0全部
  Future<OrderList> orderList(int storeId, int status, int page, CancelToken cancelToken) async {
    var params = {'s': status, 'p': page, 'ps': 10};
    var response = await _mainClient.get(
      storeId == null ? '/api/order/list' : '/api/store/$storeId/order',
      queryParameters: params,
      cancelToken: cancelToken,
    );
    return OrderList.fromJson(response.data);
  }

  /// 订单详情
  Future<OrderDetail> orderDetail(int storeId, String code, CancelToken cancelToken) async {
    var response = await _mainClient.get(
      storeId == null ? '/api/order/$code' : '/api/store/$storeId/order/$code',
      cancelToken: cancelToken,
    );
    return OrderDetail.fromJson(response.data);
  }

  /// 店铺详情
  Future<StoreDetail> storeDetail(int id, CancelToken cancelToken) async {
    var params = {'clientId': _clientId, 'storeId': id};
    var response = await _mainClient.post(
      '/api/store/detail',
      data: params,
      cancelToken: cancelToken,
    );
    return StoreDetail.fromJson(response.data);
  }

  /// 银行卡列表
  Future<List<Bank>> bankList() async {
    var response = await _mainClient.get('/api/bank/list');
    return response.data.map<Bank>((value) => Bank.fromJson(value)).toList();
  }

  /// 银行卡删除
  Future bankDelete(int id) async {
    var response = await _mainClient.get('/api/bank/delete/$id');
    return response.data;
  }

  /// 银行账户类型
  Future<Map<String, dynamic>> bankType() async {
    var response = await _mainClient.get('/api/bank/accounttype');
    return response.data;
  }

  /// 银行账户更新
  Future bankUpdate(Bank bank) async {
    var response = await _mainClient.post('/api/bank/update', data: bank);
    return response.data;
  }

  /// 业务申请第一步：获取当前用户可以申请的业务类型列表
  Future<List<BusinessType>> businessApplyType() async {
    var response = await _mainClient.get('/api/business/apply');
    return response.data.map<BusinessType>((value) => BusinessType.fromJson(value)).toList();
  }

  /// 业务申请第二步：获取申请的业务类型下可选的业务级别列表
  Future<List<BusinessLevel>> businessApplyLevel(String type) async {
    var response = await _mainClient.get('/api/business/apply/$type');
    return response.data.map<BusinessLevel>((value) => BusinessLevel.fromJson(value)).toList();
  }

  /// 业务申请第三步：获得当前店铺申请目标业务类型需要满足的购物条件
  Future<BusinessCondition> businessApplyCondition(String type, String level) async {
    var response = await _mainClient.get('/api/business/apply/$type/$level');
    return BusinessCondition.fromJson(response.data);
  }

  /// 业务申请第四步：用户选购的商品信息提交接口
  Future<List<BusinessApply>> businessApply(Map<String, dynamic> params) async {
    var response = await _mainClient.post('/api/business/apply', data: params);
    return response.data.map<BusinessApply>((value) => BusinessApply.fromJson(value)).toList();
  }

  /// 店铺提现记录查询
  Future<List<Withdraw>> withdrawQuery(int storeId, int page) async {
    var params = {'sid': storeId, 'pi': page, 'ps': 10};
    var response = await _mainClient.get('/api/withdraw/query', queryParameters: params);
    return response.data.map<Withdraw>((value) => Withdraw.fromJson(value)).toList();
  }

  /// 提现记录申请审核
  Future withdrawApply(int id) async {
    var response = await _mainClient.get('/api/withdraw/apply/$id');
    return response.data;
  }

  /// 撤回已提交的提现申请
  Future withdrawCancel(int id) async {
    var response = await _mainClient.get('/api/withdraw/cancel/$id');
    return response.data;
  }

  /// 撤回已提交的提现申请
  Future withdrawDelete(int id) async {
    var response = await _mainClient.get('/api/withdraw/delete/$id');
    return response.data;
  }

  /// 获取店铺可提现账户名称和余额
  Future<Map<String, dynamic>> withdrawAccount() async {
    var response = await _mainClient.get('/api/withdraw/account');
    return response.data;
  }

  /// 创建店铺提现记录
  Future withdrawCreate(Map<String, dynamic> params) async {
    var response = await _mainClient.post('/api/withdraw/create', data: params);
    return response.data;
  }

  /// 账户列表查询接口
  Future<List<Account>> accountList(String category) async {
    var response = await _mainClient.get('/api/useraccount/list/$category');
    return response.data.map<Account>((value) => Account.fromJson(value)).toList();
  }

  /// 当前用户的账户资金变动详情查询接口
  Future<List<AccountDetail>> accountDetail(int id, int page) async {
    var params = {'id': id, 'pi': page, 'ps': 10};
    var response = await _mainClient.get('/api/useraccount/detail', queryParameters: params);
    return response.data.map<AccountDetail>((value) => AccountDetail.fromJson(value)).toList();
  }

  /// 获取用户信息接口
  Future<List<Message>> messageQuery(int page, CancelToken cancelToken) async {
    var params = {'pi': page, 'ps': 10};
    var response = await _mainClient.get('/api/usermessage/query',
        queryParameters: params, cancelToken: cancelToken);
    return response.data.map<Message>((value) => Message.fromJson(value)).toList();
  }

  /// 用户信息已阅
  Future messageView(int id) async {
    var response = await _mainClient.get('/api/usermessage/view/$id');
    return response.data;
  }

  /// 店铺商品查询接口
  Future<StoreProductQuery> storeProductQuery(
    int storeId,
    int categoryId,
    int storeAreaId,
    int page,
    CancelToken cancelToken,
  ) async {
    var params = {
      'categoryId': categoryId,
      'clientId': _clientId,
      'pageIndex': page,
      'pageSize': 10,
      'queryKey': null,
      'storeAreaId': storeAreaId,
      'storeId': storeId,
    };
    var response = await _mainClient.post(
      '/api/store/product/query',
      data: params,
      cancelToken: cancelToken,
    );
    return StoreProductQuery.fromJson(response.data);
  }

  /// 商品搜索
  Future<Search> search(String keyword, int page) async {
    var params = {'q': keyword, 'p': page, 'ps': 10};
    var response = await _mainClient.get('/api/search', queryParameters: params);
    return Search.fromJson(response.data);
  }

  /// 店铺搜索
  Future storeSearch(String keyword, int page) async {
    var params = {'q': keyword, 'p': page, 'ps': 10};
    var response = await _mainClient.get('/api/storesearch', queryParameters: params);
    return StoreSearch.fromJson(response.data);
  }

  /// 获取店铺商品分类信息
  Future<StoreCategories> storeCategories(
    int storeId,
    int parentCategoryId,
    int layerLevel,
    CancelToken cancelToken,
  ) async {
    var params = <String, dynamic>{};
    params['clientId'] = _clientId;
    params['storeId'] = storeId;
    params['parentCategoryId'] = parentCategoryId;
    params['layerLevel'] = layerLevel;
    var response = await _mainClient.post(
      '/api/store/categories/v2',
      data: params,
      cancelToken: cancelToken,
    );
    return StoreCategories.fromJson(response.data);
  }

  /// 店铺新闻公告查询接口
  Future<NewsQuery> newsQuery(Map<String, dynamic> params) async {
    // params['storeId'] = storeId;
    // params['linkType'] = linkType;
    // params['queryKey'] = _queryKey;
    // params['pageIndex'] = 0;
    params['pageSize'] = 10;
    params['clientId'] = _clientId;
    var response = await _mainClient.post('/api/news/query', data: params);
    return NewsQuery.fromJson(response.data);
  }

  /// 获取锁粉列表
  Future<UserInvited> userInvited(int currentUserId, int targetUserId, int page) async {
    var params = <String, dynamic>{};
    params['currentUserId'] = currentUserId;
    params['targetUserId'] = targetUserId;
    params['levelOffset'] = 1;
    params['pageIndex'] = page;
    params['pageSize'] = 10;
    var response = await _mainClient.post('/api/user/invited', data: params);
    return UserInvited.fromJson(response.data);
  }

  /// 查询用户续费信息接口
  Future<UserRenewList> userRenewList(int userId, String businessType) async {
    var params = <String, dynamic>{};
    params['u'] = userId;
    params['b'] = businessType;
    var response = await _mainClient.get('/api/user/renew/list', queryParameters: params);
    return UserRenewList.fromJson(response.data);
  }

  /// 店铺申请查询
  Future<StoreApplyQuery> storeApplyQuery(CancelToken cancelToken) async {
    var response = await _mainClient.post('/api/store/apply/query');
    return StoreApplyQuery.fromJson(response.data);
  }

  /// 店铺标准申请接口
  Future<StoreApplyQuery> storeApplyStd(
    Map<String, dynamic> params,
    CancelToken cancelToken,
  ) async {
    // params['id'] = id;
    // params['name'] = name;
    // params['logoFile'] = logoFile;
    // params['idCardFile'] = idCardFile;
    // params['licenseFile'] = licenseFile;

    var logoFile = params['logoFile'] as File;
    var idCardFile = params['idCardFile'] as File;
    var licenseFile = params['licenseFile'] as File;
    if (logoFile != null) {
      params['logoFile'] = await MultipartFile.fromFile(logoFile.path, filename: 'logoFile.png');
    }
    if (idCardFile != null) {
      params['idCardFile'] =
          await MultipartFile.fromFile(idCardFile.path, filename: 'idCardFile.png');
    }
    if (licenseFile != null) {
      params['licenseFile'] =
          await MultipartFile.fromFile(licenseFile.path, filename: 'licenseFile.png');
    }

    debugPrint('$params');
    var response = await _mainClient.post(
      '/api/store/apply/std',
      data: FormData.fromMap(params),
      cancelToken: cancelToken,
    );
    return StoreApplyQuery.fromJson(response.data);
  }

  /// 订单再次支付
  Future orderRepay(String code) async {
    var response = await _mainClient.post('/api/order/repay/$code');
    return response.data;
  }

  /// 订单确认收货
  Future orderConfirmReceipt(String code) async {
    var response = await _mainClient.post('/api/order/$code/confirm');
    return response.data;
  }

  /// 删除超时订单
  Future orderDelete(String code) async {
    var response = await _mainClient.post('/api/order/$code/delete');
    return response.data;
  }

  /// 获取当前店铺的各类信息统计数量
  Future<StoreTotal> storeTotal(int storeId) async {
    var params = <String, dynamic>{};
    params['sid'] = storeId;
    var response = await _mainClient.get('/api/store/total', queryParameters: params);
    return StoreTotal.fromJson(response.data);
  }

  /// 通过物流单号和快递公司编码查询快递物流信息，返回的数据第三方数据，只做中转
  Future<Logistics> logistics(String num, String type) async {
    var params = <String, dynamic>{};
    params['num'] = num;
    params['type'] = type;
    var response = await _mainClient.get('/api/logistics', queryParameters: params);
    return Logistics.fromJson(jsonDecode(response.data));
  }

  /// 店铺LOGO信息查询接口
  Future<String> storeLogoQuery() async {
    var response = await _mainClient.get('/api/store/logo/query');
    return response.data;
  }
}
